package com.yudaob2b.elong.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yudaob2b.common.utils.XMLUtil;
import com.yudaob2b.elong.constant.ElongConstant;
import com.yudaob2b.elong.entity.vo.*;
import com.yudaob2b.elong.entity.vo.hoteldetail.SingleHotel;
import com.yudaob2b.elong.entity.vo.hotellist.HotelIndex;
import com.yudaob2b.elong.entity.vo.result.*;
import com.yudaob2b.elong.enums.EnumIncrType;
import com.yudaob2b.elong.enums.EnumLocal;
import com.yudaob2b.elong.enums.EnumPaymentType;
import com.yudaob2b.elong.utils.HttpUtil;
import com.yudaob2b.elong.utils.ToolUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;


/**
 * 静态数据请求服务类
 *
 * @author Kidd.Tan
 * @email 298023780@qq.com
 * @date 7/5/18 10:33 PM
 */
@Service("httpStaticService")
public class HttpStaticService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${elong.static.host.url}")
    private String ELONG_STATIC_HOST_URL;

    @Value("${elong.dynamic.host.url}")
    private String ELONG_DYNAMIC_HOST_URL;

    @Value("${elong.app.key}")
    private String ELONG_APP_KEY;

    @Value("${elong.app.secret}")
    private String ELONG_APP_SECRET;

    @Value("${elong.user}")
    private String ELONG_USER;

    /**
     * 酒店列表-静态信息url
     */
    private final static String GET_HOTELLIST_URL = "[host]/xml/v2.0/hotel/hotellist.xml";

    /**
     * 酒店详情-静态信息url
     * host：域名
     * lang：cn(国内酒店)/en(国外酒店)
     * num：hotelid后两位
     * hotelid：酒店ID
     */
    private final static String GET_HOTEL_DETAIL_URL = "[host]/xml/v2.0/hotel/[lang]/[num]/[hotelid].xml";


    /**
     * 获取接口数据－酒店列表
     *
     * @return
     */
    public HotelIndex getHostList() {
        String url = GET_HOTELLIST_URL.replace("[host]", ELONG_STATIC_HOST_URL);
        //String reponseStr = HttpUtils.get(url, true);
        String reponseStr = HttpUtil.Send("GET", url, "");
        HotelIndex hotelIndex = (HotelIndex) XMLUtil.convertXmlStrToObject(HotelIndex.class, reponseStr);

        return hotelIndex;
    }

    /**
     * 获取接口数据－酒店列表
     *
     * @return
     */
    public SingleHotel getHostDetail(String lang, String hotelId) {
        String url = GET_HOTEL_DETAIL_URL.replace("[host]", ELONG_STATIC_HOST_URL)
                .replace("[lang]", lang)
                .replace("[num]", hotelId.substring(hotelId.length() - 2, hotelId.length()))
                .replace("[hotelid]", hotelId);
        //String reponseStr = HttpUtils.get(url, true);
        String reponseStr = HttpUtil.Send("GET", url, "");
        SingleHotel singleHotel = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            singleHotel = (SingleHotel) XMLUtil.convertXmlStrToObject(SingleHotel.class, reponseStr);
        }

        return singleHotel;
    }

    /**
     * 国内酒店-产品详情（hotel.data.rp）
     *
     * @param hotelId
     * @param paymentType
     * @param options
     */
    public HotelDataRpResult gethotelDataRp(String hotelId, EnumPaymentType paymentType, String options) {
        HotelDateRpCondition condition = new HotelDateRpCondition();
        condition.setHotelIds(hotelId);
        condition.setPaymentType(paymentType);
        condition.setOptions(options);

        BaseRequst<HotelDateRpCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_DATA_RP, dataJson);
        //logger.info("hotelDataRp: {}", reponseStr);
        HotelDataRpResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelDataRpResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-房态库存（hotel.data.inventory）
     *
     * @param hotelId
     * @param hotelCodes
     * @param roomTypeId
     * @param startDate
     * @param endDate
     * @param isNeedInstantConfirm
     * @return
     */
    public HotelDataInventoryResult getHotelDataInventory(String hotelId, String hotelCodes, String roomTypeId, Date startDate, Date endDate, String isNeedInstantConfirm) {
        InventoryCondition condition = new InventoryCondition();
        condition.setHotelIds(hotelId);
        condition.setStartDate(startDate);
        condition.setEndDate(endDate);
        if (StringUtils.isNotEmpty(hotelCodes)) {
            condition.setHotelCodes(hotelCodes);
        }
        if (StringUtils.isNotEmpty(roomTypeId)) {
            condition.setRoomTypeId(roomTypeId);
        }
        if (StringUtils.isNotEmpty(isNeedInstantConfirm)) {
            if ("true".equals(isNeedInstantConfirm)) {
                condition.setIsNeedInstantConfirm(true);
            } else if ("false".equals(isNeedInstantConfirm)) {
                condition.setIsNeedInstantConfirm(false);
            }
        }

        BaseRequst<InventoryCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_DATA_INVENTORY, dataJson);
        // logger.info("hotelDataInventory: {}",reponseStr);
        HotelDataInventoryResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelDataInventoryResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-产品价格（hotel.data.rate）
     *
     * @param hotelId
     * @param hotelCodes
     * @param paymentType
     * @param startDate
     * @param endDate
     * @return
     */
    public HotelDataRateResult getHotelDataRate(String hotelId, String hotelCodes, EnumPaymentType paymentType, Date startDate, Date endDate) {
        RateCondition condition = new RateCondition();
        condition.setHotelIds(hotelId);
        condition.setPaymentType(paymentType);
        condition.setStartDate(startDate);
        condition.setEndDate(endDate);
        if (StringUtils.isNotEmpty(hotelCodes)) {
            condition.setHotelCodes(hotelCodes);
        }

        BaseRequst<RateCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_DATA_RATE, dataJson);
        //logger.info("hotelDataRate: {}", reponseStr);
        HotelDataRateResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelDataRateResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-增量编号
     *
     * @param lastTime
     * @param incrType
     * @return
     */
    public HotelIncrIdResult getHotelIncrId(Date lastTime, EnumIncrType incrType) {
        IncrLastIdCondition condition = new IncrLastIdCondition();
        condition.setLastTime(lastTime);
        condition.setIncrType(incrType);

        BaseRequst<IncrLastIdCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_INCR_ID, dataJson);
        HotelIncrIdResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelIncrIdResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-状态增量，对应hotel.data.rp
     *
     * @param lastId
     * @return
     */
    public HotelIncrStateResult gethotelIncrState(long lastId) {
        IncrCondition condition = new IncrCondition();
        condition.setLastId(lastId);

        BaseRequst<IncrCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_INCR_STATE, dataJson);
        HotelIncrStateResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelIncrStateResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-库存增量，对应hotel.data.inventory
     *
     * @param lastId
     * @return
     */
    public HotelIncrInvResult gethotelIncrInv(long lastId) {
        IncrCondition condition = new IncrCondition();
        condition.setLastId(lastId);

        BaseRequst<IncrCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_INCR_INV, dataJson);
        HotelIncrInvResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelIncrInvResult.class);
        }

        return resultVo;
    }

    /**
     * 国内酒店-价格增量，对应hotel.data.rate
     *
     * @param lastId
     * @return
     */
    public HotelIncrRateResult gethotelIncrRate(long lastId) {
        IncrCondition condition = new IncrCondition();
        condition.setLastId(lastId);

        BaseRequst<IncrCondition> req = new BaseRequst<>();
        req.Version = ElongConstant.VERSION;
        req.Local = EnumLocal.zh_CN;
        req.Request = condition;
        String dataJson = this.objectToJson(req);

        String reponseStr = dynamicDateGet(ElongConstant.HOTEL_INCR_RATE, dataJson);
        HotelIncrRateResult resultVo = null;
        if (StringUtils.isNotEmpty(reponseStr)) {
            resultVo = JSONObject.parseObject(reponseStr, HotelIncrRateResult.class);
        }

        return resultVo;
    }

    private String dynamicDateGet(String method, String dataJson) {
        long epoch = System.currentTimeMillis() / 1000;
        String sig = ToolUtil.md5(epoch + ToolUtil.md5(dataJson + ELONG_APP_KEY) + ELONG_APP_SECRET);
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(ELONG_DYNAMIC_HOST_URL).append("/rest?")
                .append("user=").append(ELONG_USER)
                .append("&method=").append(method)
                .append("&timestamp=").append(epoch)
                .append("&format=json")
                .append("&data=").append(dataJson)
                .append("&signature=").append(sig);
        String url = urlBuilder.toString().replaceAll(" ", "%20");
        //System.out.println(url);
        return HttpUtil.Send("GET", url, "");
    }

    private String objectToJson(Object value) {
        String str = null;
        str = JSON.toJSONStringWithDateFormat(value, "yyyy-MM-dd HH:mm:ss");
        return str;
    }
}
